﻿using System.Collections.Generic;

namespace PathFind.Algo {
    public class NodePool<TNode> where TNode : Node, new() {
        private List<TNode[]> _bucket = new List<TNode[]>();
        private int numDistributedNodes, bucketId, nodeId;
        private readonly int sizePerBucket;

        public NodePool() {
            sizePerBucket = 1024;
            numDistributedNodes = bucketId = nodeId = 0;
            TNode[] arr = new TNode[sizePerBucket];
            _bucket.Add(arr);
        }

        public TNode GetNewNode(Coordinate pos, Coordinate goalPos, Direction dir, Node parent) {
            if (bucketId > _bucket.Count - 1) {
                TNode[] arr = new TNode[sizePerBucket];
                _bucket.Add(arr);
            }

            if (_bucket[bucketId][nodeId] == null) {
                _bucket[bucketId][nodeId] = new TNode();
            }

            var value = _bucket[bucketId][nodeId];
            value.Reset(pos, parent, goalPos, dir);
            numDistributedNodes++;
            nodeId++;
            if (nodeId == sizePerBucket) {
                nodeId = 0;
                bucketId++;
            }

            return value;
        }

        public void Reset() {
            numDistributedNodes = bucketId = nodeId = 0;
        }

        public int NumDistributedNodes => numDistributedNodes;
    }
}